package com.lwf.smartseniorcare.service;

import com.lwf.smartseniorcare.dto.ActivityRecordDTO;
import com.lwf.smartseniorcare.entity.ActivityRecord;
import com.lwf.smartseniorcare.entity.Elderly;
import com.lwf.smartseniorcare.repository.ActivityRecordRepository;
import com.lwf.smartseniorcare.repository.ElderlyRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ActivityRecordService {

    @Autowired
    ActivityRecordRepository activityRecordRepository;

    @Autowired
    ElderlyRepository elderlyRepository;

    // Convert Entity to DTO
    private ActivityRecordDTO convertToDTO(ActivityRecord record) {
        ActivityRecordDTO dto = new ActivityRecordDTO();
        dto.setId(record.getId());
        dto.setElderlyId(record.getElderly().getId());
        dto.setActivityDate(record.getActivityDate());
        dto.setActivityType(record.getActivityType());
        dto.setDurationMinutes(record.getDurationMinutes());
        dto.setIntensity(record.getIntensity());
        dto.setNotes(record.getNotes());
        return dto;
    }

    // Convert DTO to Entity
    private ActivityRecord convertToEntity(ActivityRecordDTO dto) {
        ActivityRecord record = new ActivityRecord();
        if (dto.getId() != null) {
            record.setId(dto.getId());
        }
        Elderly elderly = elderlyRepository.findById(dto.getElderlyId())
                .orElseThrow(() -> new RuntimeException("Elderly not found with id: " + dto.getElderlyId()));
        record.setElderly(elderly);
        record.setActivityDate(dto.getActivityDate());
        record.setActivityType(dto.getActivityType());
        record.setDurationMinutes(dto.getDurationMinutes());
        record.setIntensity(dto.getIntensity());
        record.setNotes(dto.getNotes());
        return record;
    }

    public List<ActivityRecordDTO> getAllActivityRecords() {
        return activityRecordRepository.findAll().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    public ActivityRecordDTO getActivityRecordById(Long id) {
        ActivityRecord record = activityRecordRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("Activity record not found with id: " + id));
        return convertToDTO(record);
    }

    public ActivityRecordDTO createActivityRecord(ActivityRecordDTO activityRecordDTO) {
        ActivityRecord record = convertToEntity(activityRecordDTO);
        record = activityRecordRepository.save(record);
        return convertToDTO(record);
    }

    public ActivityRecordDTO updateActivityRecord(Long id, ActivityRecordDTO activityRecordDTO) {
        ActivityRecord existingRecord = activityRecordRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("Activity record not found with id: " + id));
        
        ActivityRecord updatedRecord = convertToEntity(activityRecordDTO);
        updatedRecord.setId(id); // Ensure we don't create a new entity
        
        updatedRecord = activityRecordRepository.save(updatedRecord);
        return convertToDTO(updatedRecord);
    }

    public void deleteActivityRecord(Long id) {
        ActivityRecord record = activityRecordRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("Activity record not found with id: " + id));
        activityRecordRepository.delete(record);
    }

    public List<ActivityRecordDTO> getActivityRecordsByElderly(Long elderlyId) {
        Elderly elderly = elderlyRepository.findById(elderlyId)
                .orElseThrow(() -> new RuntimeException("Elderly not found with id: " + elderlyId));
        return activityRecordRepository.findByElderlyOrderByActivityDateDesc(elderly).stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    public List<ActivityRecordDTO> getActivityRecordsByElderlyAndDateRange(Long elderlyId, Date startDate, Date endDate) {
        Elderly elderly = elderlyRepository.findById(elderlyId)
                .orElseThrow(() -> new RuntimeException("Elderly not found with id: " + elderlyId));
        return activityRecordRepository.findByElderlyAndActivityDateBetween(elderly, startDate, endDate).stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    public List<ActivityRecordDTO> getActivityRecordsByElderlyAndType(Long elderlyId, String activityType) {
        Elderly elderly = elderlyRepository.findById(elderlyId)
                .orElseThrow(() -> new RuntimeException("Elderly not found with id: " + elderlyId));
        return activityRecordRepository.findByElderlyAndActivityType(elderly, activityType).stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    public List<ActivityRecordDTO> getRecentActivityRecordsByElderly(Long elderlyId) {
        Elderly elderly = elderlyRepository.findById(elderlyId)
                .orElseThrow(() -> new RuntimeException("Elderly not found with id: " + elderlyId));
        return activityRecordRepository.findTop10ByElderlyOrderByActivityDateDesc(elderly).stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
}
